/*

  The contents of this file are subject to the Mozilla Public License Version
  1.1 (the "License"); you may not use this file except in compliance with
  the License. You may obtain a copy of the License at 
  
           http://www.mozilla.org/MPL/ 
  
  Software distributed under the License is distributed on an "AS IS" basis,
  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  for the specific language governing rights and limitations under the License. 
  
  The Original Code is Indigo framework applicatif.
  
  The Initial Developer of the Original Code is
  Olivier Bugalotto (aka Iteratif) <olivier.bugalotto@iteratif.net>.
  Portions created by the Initial Developer are Copyright (C) 2004-2008
  the Initial Developer. All Rights Reserved.
  
  Contributor(s) :
  
*/
package indigo.flex.core
{
	import flash.events.IOErrorEvent;
	
	import indigo.context.ApplicationContext;
	import indigo.context.ContextManager;
	import indigo.context.IApplicationContext;
	import indigo.context.XmlApplicationContext;
	import indigo.events.FactoryEvent;
	import indigo.factory.xml.IXmlObjectFactory;
	import indigo.flex.events.ApplicationEvent;
	import indigo.register.IObjectDefinitionRegistry;
	import indigo.register.ObjectDefinitionRegistry;
	
	import mx.core.Application;
	import mx.core.mx_internal;
	import mx.utils.StringUtil;
	
	use namespace mx_internal;
	
	[Event(name="ready",type="indigo.flex.events.ApplicationEvent")]

	/**
	 * Cette classe <code>IndigoApplication</code> prend en charge
	 * toute la mecanique de chargement d'un descripteur de configuration XML,
	 * de creer un referentiel et un context applicatif unique (fabrique d'objets)
	 * pour un projet Flex 3.
	 * 
	 * @example Structure de base de votre Application Flex architecture avec le framework indigo:
	 * 
	 * <listing version="3.0">
	 * &lt;?xml version="1.0" encoding="utf-8"?&gt;
	 * &lt;IndigoApplication xmlns="http://www.indigo-framework.org" xmlns:mx="http://www.adobe.com/2006/mxml"
	 * 		layout="absolute"&gt;
	 * 		...
	 * &lt;/IndigoApplication&gt;
	 * </listing>
	 * 
	 * @see indigo.register.ObjectDefinitionRegistry
	 * @see indigo.context.ApplicationContext
	 */
	public class IndigoApplication extends Application
	{
		private static var _register:IObjectDefinitionRegistry;
		
		private var _useDescriptor:Boolean = true;
		/**
		 * Savoir si la fabrique doit utiliser un descripteur pour alimenter le referentiel.
		 *  
		 * @return 
		 * 
		 */
		public function get useDescriptor():Boolean {
			return _useDescriptor;
		}
		
		[Inspectable(category="General", defaultValue="true")]
		public function set useDescriptor(value:Boolean):void {
			_useDescriptor = value;
		}
		
		private var _urlDescriptor:String;
		/**
		 * Obtenir le chemin du fichier descripteur 
		 * @return 
		 * 
		 */
		public function get urlDescriptor():String {
			return _urlDescriptor;
		}
		
		/**
		 * Definit un chemin vers un fichier descripteur 
		 * @param value
		 * 
		 */
		[Inspectable(category="General", defaultValue="app-config.xml", format="File")]
		public function set urlDescriptor(value:String):void {
			_urlDescriptor = value;
		}
		
		/**
		 * Creer un objet <code>IndigoApplication</code> pour un projet
		 * base sur le framework Flex. 
		 * 
		 */
		public function IndigoApplication()
		{
			super();
			_register = new ObjectDefinitionRegistry();
		}
		
		public override function initialize():void {
			super.initialize();
			
			if(!useDescriptor) {
				initializeRegister(_register);
				initializeContext(_register);
			} else
				loadDescriptor();
		}
		
		/**
		 * perhaps redefined to program the repository
		 *  
		 * @param register	Reference to repository use by the context of the application
		 * 
		 */
		protected function initializeRegister(register:IObjectDefinitionRegistry):void {
			// Redefinir la methode si configuration par code
		}
		
		/**
		 * This method allows to load descriptor file 
		 * 
		 */
		private function loadDescriptor():void {
			var url:String;
			if(urlDescriptor) {
				url = urlDescriptor;
			} else if (systemManager.loaderInfo.parameters.url != undefined) {
				url = systemManager.loaderInfo.parameters.url
			} else {
				// fix: no using extension -config.xml reserved for RPC
				url = StringUtil.substitute("{0}-cfg.xml",systemManager.info()["mainClassName"]);
			}
			
			ApplicationContext.url = url;
			ApplicationContext.start(onReady);
		}
		
		private function initializeContext(registry:IObjectDefinitionRegistry = null):void {			
			// Creation du context applicatif
			var context:IApplicationContext = new XmlApplicationContext("contextApp",registry);
			ContextManager.registerContext(context);
			
			onReady();
		}
		
		private function onReady():void {
			var evt:ApplicationEvent = new ApplicationEvent(ApplicationEvent.READY);
			dispatchEvent(evt);
		}
	}
}